#define	STOPPING_CONDITION	150 //seconds.
#define	DISCARD	50000
void compute_performance(int sd, short event, void* arg);
double calculate_throughput(int bytes, double elapsed_time);
double measure_time_difference(struct timeval now, struct timeval past);

//----------for acceptor: thus prefixed by a------------------------------
typedef struct a_performance_t {

	double total_time;
	double interval_time;

	double interval_delivery_throughput;
	double interval_sending_throughput;
	double interval_recv_throughput;
	double total_delivery_throughput;
	double total_sending_throughput;
	double interval_bytes_sent;
	double interval_bytes_received;
	double interval_num_entrance;
	double total_num_entrance;
	double interval_latency;
	double total_latency;

	int interval_num_packets_delivered;
	int interval_num_packets_sent;
	int interval_num_packets_received;
	int total_num_packets_delivered;
	int total_num_packets_received;
	int total_num_packets_sent;
	int interval_num_packets_proposer_to_acceptor_0;
	int interval_num_paxos_packets_received;
	int total_num_instances;
	int highest_deliverable_inst_id;

} a_performance;

a_performance a_performances[200];
a_performance *a_interval_performance;
const char *a_performance_file;
int a_next_performance_index;

void a_calculate_performance_over_all_interval_uptonow();
void a_store_performance_in_file(const char * performance_file, const char * latency_file, int num_entries);
void a_store_performance_in_array(a_performance * performances_array, int * performance_index, a_performance *i_p);
void a_print_performance(a_performance *p);
void a_nulify_performance(a_performance *p);

//-----------for learner_proposer: thus prefixed by lp------------------------------
typedef struct lp_performance_t {

	int interval_num_packets_delivered;
	int interval_num_packets_proposed;
	int interval_num_packets_received;
	int total_num_packets_delivered;
	int total_num_packets_received;
	int total_num_packets_proposed;
	int highest_deliverable_inst_id;
	int highest_self_deliverable;
	int next_location_index_in_proposer;
	int num_packets_delivered_latency;

	double total_time;
	double interval_time;
	double interval_delivery_throughput;
	double interval_sending_throughput;
	double interval_recv_throughput;
	double interval_prop_throughput;
	double interval_latency;
	double interval_num_entrance;
	double total_delivery_throughput;
	double total_sending_throughput;
	double total_latency;
	double total_num_entrance;
	double interval_bytes_received;
	double interval_bytes_forwarded;
	double interval_bytes_proposed;

	int latency_counter;
	double latency_sd;
	double latency_avg;
	double latency_sq_sum;
	double latency_sum;

	int num_interrupts;
	int num_interrupts_new_msg;


} lp_performance;

lp_performance lp_performances[200];
lp_performance *lp_interval_performance;
const char *lp_performance_file;
const char *lp_latency_file;
const char *lp_sd_avg_file;
int lp_next_performance_index;

void lp_calculate_performance_over_all_interval_uptonow();
void lp_store_performance_in_file(const char * performance_file, const char * latency_file, const char * sd_avg_file, int num_entries);
void lp_store_performance_in_array(lp_performance * performances_array, int * performance_index, lp_performance *i_p);
void lp_print_performance(lp_performance *p);
void lp_nulify_performance(lp_performance *p);

//--------------------ALP-------------------
typedef struct alp_performance_t {

	int interval_num_packets_delivered;
	int interval_num_packets_sent;
	int total_num_packets_delivered;
	int interval_num_packets_received;
	int total_num_packets_received;
	int total_num_packets_sent;
	int interval_num_packets_proposer_to_acceptor_0;
	int interval_num_paxos_packets_received;
	int total_num_instances;
	int highest_deliverable_inst_id;
	int highest_self_deliverable;
	int next_location_index_in_proposer;
	int interval_num_packets_proposed;
	int total_num_packets_proposed;
	int num_packets_delivered_latency;
	int next_instance_id;

	double total_time;
	double interval_time;
	double interval_delivery_throughput;
	double interval_bytes_sent;
	double interval_bytes_proposed;
	double interval_sending_throughput;
	double interval_bytes_received;
	double total_delivery_throughput;
	double total_sending_throughput;
	double interval_latency;
	double total_latency;
	double interval_recv_throughput;
	double interval_num_entrance;
	double total_num_entrance;
	double interval_propos_thr;

	int latency_counter;
	double latency_sd;
	double latency_avg;
	double latency_sq_sum;
	double latency_sum;

	int num_interrupts_new_msgs;
	int num_interrupts_phase2b;
	int num_interrupts_phase2b_individual;
	int num_interrupts;

} alp_performance;

alp_performance alp_performances[200];
alp_performance *alp_interval_performance;
const char *alp_performance_file;
const char *alp_latency_file;
const char *alp_sd_avg_file;
int alp_next_performance_index;

void alp_calculate_performance_over_all_interval_uptonow();
void alp_store_performance_in_file(const char * performance_file, const char * latency_file, const char * sd_avg_file, int num_entries);
void alp_store_performance_in_array(alp_performance * performances_array, int * performance_index, alp_performance *i_p);
void alp_print_performance(alp_performance *p);
void alp_nulify_performance(alp_performance *p);

